package com.handinfo.android.core.graphics;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.text.TextPaint;

import com.handinfo.android.DWGameManager;
import com.handinfo.android.utils.Tools;

public class DWGraphics implements ITrans
{
	private static final DWFont DefaultFont = DWFont.getDefaultFont();

	private Bitmap m_bitmap;

	private Matrix m_matrix;
	private ColorMatrix m_colorMatrix;
	private ColorMatrixColorFilter m_colorMatrixFilter;

	private Canvas m_canvas;
	private Paint m_paint;
	private RectF m_clip;
	private Rect m_rect;
	private RectF m_rectF;
	private DWFont m_font;
	private int m_width, m_height;

	public DWGraphics()
	{
		initDWGraphics();
	}

	public DWGraphics(Bitmap bitmap)
	{
		initDWGraphics(bitmap);
	}

	public void initDWGraphics()
	{
		m_matrix = new Matrix();
		m_colorMatrix = new ColorMatrix();
		m_width = DWGameManager.Screen_Width;
		m_height = DWGameManager.Screen_Height;

		m_paint = new Paint();
		m_rect = new Rect();
		m_rectF = new RectF();
		m_font = DefaultFont;
		m_paint.setTypeface(m_font.getTypeface());
	}

	public void initDWGraphics(Bitmap bitmap)
	{
		m_bitmap = bitmap;
		m_matrix = new Matrix();
		m_colorMatrix = new ColorMatrix();
		m_canvas = new Canvas(m_bitmap);
		m_width = m_bitmap.getWidth();
		m_height = m_bitmap.getHeight();
		m_clip = new RectF(m_canvas.getClipBounds());
		m_canvas.clipRect(m_clip);
		m_canvas.save(Canvas.CLIP_SAVE_FLAG);
		m_paint = new Paint();
		m_rect = new Rect();
		m_rectF = new RectF();
		m_font = DefaultFont;
		m_paint.setTypeface(m_font.getTypeface());
	}

	public void reset()
	{
		m_paint.reset();
		m_matrix.reset();
		m_colorMatrix.reset();
		m_clip = new RectF(m_canvas.getClipBounds());
		setFont(DefaultFont);
		m_canvas.clipRect(m_clip);
		m_canvas.save(Canvas.CLIP_SAVE_FLAG);
	}

	public void setBitmap(Bitmap bitmap)
	{
		m_bitmap = bitmap;
		m_canvas.setBitmap(bitmap);
		m_width = m_bitmap.getWidth();
		m_height = m_bitmap.getHeight();
		m_clip = new RectF(m_canvas.getClipBounds());
		m_canvas.clipRect(m_clip);
		m_canvas.save(Canvas.CLIP_SAVE_FLAG);
	}

	public void setCanvas(Canvas canvas)
	{
		m_canvas = canvas;
		m_clip = new RectF(m_canvas.getClipBounds());
		m_canvas.clipRect(m_clip);
		m_canvas.save(Canvas.CLIP_SAVE_FLAG);
	}

	public Paint getPaint()
	{
		return m_paint;
	}

	public Canvas getCanvas()
	{
		return m_canvas;
	}

	public void setFont(DWFont font)
	{
		m_font = font;
	}

	public int getFontHeight()
	{
		return m_font.getHeight();
	}
	
	public void setClip(RectF rect)
	{
		setClip(rect.left, rect.top, rect.width(), rect.height());
	}
	
	public void setClip(float x, float y, float w, float h)
	{
		if (x < m_clip.left || x + w > m_clip.right || y < m_clip.top
				|| y + h > m_clip.bottom) {
			try {
				if (m_canvas.getSaveCount() > 0) {
					m_canvas.restore();
					m_canvas.save(Canvas.CLIP_SAVE_FLAG);
				}
			}
			catch (Exception e) {
				Tools.debug(e);
			}
		}
		
		m_clip.left = x;
		m_clip.top = y;
		m_clip.right = x + w;
		m_clip.bottom = y + h;
		m_canvas.clipRect(m_clip);
	}

	public float getClipX()
	{
		return m_clip.left;
	}

	public float getClipY()
	{
		return m_clip.top;
	}

	public float getClipWidth()
	{
		return m_clip.right;
	}

	public float getClipHeight()
	{
		return m_clip.bottom;
	}
	
	public RectF getClipRect()
	{
		return m_clip;
	}

	public void drawString(String text, int color, int x, int y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= m_font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= m_font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)m_font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(color);
		m_canvas.drawText(text, rx, ry, paint);
		paint.setFlags(flag);
	}

	public void drawString(String text, int color, float x, float y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= m_font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= m_font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)m_font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(color);
		m_canvas.drawText(text, rx, ry, paint);
		paint.setFlags(flag);
	}
	
	public void drawShadowString(String text, int shadowColor, int textColor, int x, int y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= m_font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= m_font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)m_font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setColor(shadowColor);
		paint.setStrokeWidth(2);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setStyle(Style.FILL);
		paint.setColor(textColor);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setFlags(flag);
	}

	public void drawShadowString(String text, int shadowColor, int textColor, float x, float y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= m_font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= m_font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= m_font.stringWidth(text) / 2;
				ry -= m_font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)m_font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setColor(shadowColor);
		paint.setStrokeWidth(2);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setStyle(Style.FILL);
		paint.setColor(textColor);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setFlags(flag);
	}
	
	public void drawString(DWFont font, String text, int color, int x, int y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(color);
		m_canvas.drawText(text, rx, ry, paint);
		paint.setFlags(flag);
	}

	public void drawString(DWFont font, String text, int color, float x, float y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= m_font.stringWidth(text);
				ry -= m_font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(color);
		m_canvas.drawText(text, rx, ry, paint);
		paint.setFlags(flag);
	}
	
	public void drawShadowString(DWFont font, String text, int shadowColor, int textColor, int x, int y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setColor(shadowColor);
		paint.setStrokeWidth(2);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setStyle(Style.FILL);
		paint.setColor(textColor);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setFlags(flag);
	}

	public void drawShadowString(DWFont font, String text, int shadowColor, int textColor, float x, float y, int anchor)
	{
		if (text == null)
			return;
		float rx = x;
		float ry = y;
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				ry -= font.getFontMetrics().ascent;
				break;
			case LEFT | BOTTOM:
				ry -= font.getFontMetrics().descent;
				break;
			case HCENTER | TOP:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().ascent;
				break;
			case HCENTER | BOTTOM:
				rx -= font.stringWidth(text) / 2;
				ry -= font.getFontMetrics().descent;
				break;
			case RIGHT | TOP:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().ascent;
				break;
			case RIGHT | BOTTOM:
				rx -= font.stringWidth(text);
				ry -= font.getFontMetrics().descent;
				break;
			default:
				throw new IllegalArgumentException("drawString() parameter error!");
		}
		TextPaint paint = (TextPaint)font.getPaint();
		int flag = paint.getFlags();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setColor(shadowColor);
		paint.setStrokeWidth(2);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setStyle(Style.FILL);
		paint.setColor(textColor);
		m_canvas.drawText(text, rx, ry, paint);
		
		paint.setFlags(flag);
	}

	
	public static long DrawBitmapCount;
	public static long DrawBitmapTimes;
	public static long DrawBitmapSquareAmount;
	public static boolean DEBUG_GRAPHICS = false;
	public void drawBitmap(Bitmap bitmap, float x, float y, int anchor)
	{
		m_paint.reset();
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= height / 2;
				break;
			case LEFT | BOTTOM:
				y -= height;
				break;
			case HCENTER | TOP:
				x -= width / 2;
				break;
			case HCENTER | VCENTER:
				x -= width / 2;
				y -= height / 2;
				break;
			case HCENTER | BOTTOM:
				x -= width / 2;
				y -= height;
				break;
			case RIGHT | TOP:
				x -= width;
				break;
			case RIGHT | VCENTER:
				x -= width;
				y -= height / 2;
				break;
			case RIGHT | BOTTOM:
				x -= width;
				y -= height;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, x, y, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, x, y, m_paint);
		}
	}
	
	public void drawBitmap(Bitmap bitmap, float x, float y, int anchor, boolean grey)
	{
		m_paint.reset();
		ColorMatrixColorFilter cmcf;
		if (grey) {
			m_colorMatrix.reset();
			m_colorMatrix.setSaturation(0);
			cmcf = new ColorMatrixColorFilter(m_colorMatrix);
			m_paint.setColorFilter(cmcf);
			
		}
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= height / 2;
				break;
			case LEFT | BOTTOM:
				y -= height;
				break;
			case HCENTER | TOP:
				x -= width / 2;
				break;
			case HCENTER | VCENTER:
				x -= width / 2;
				y -= height / 2;
				break;
			case HCENTER | BOTTOM:
				x -= width / 2;
				y -= height;
				break;
			case RIGHT | TOP:
				x -= width;
				break;
			case RIGHT | VCENTER:
				x -= width;
				y -= height / 2;
				break;
			case RIGHT | BOTTOM:
				x -= width;
				y -= height;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, x, y, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, x, y, m_paint);
		}
	}
	
	public void drawBitmap(Bitmap bitmap, float x, float y, float w, float h, int anchor)
	{
		m_paint.reset();
		m_matrix.reset();
		
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();		
		
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= h / 2;
				break;
			case LEFT | BOTTOM:
				y -= h;
				break;
			case HCENTER | TOP:
				x -= w / 2;
				break;
			case HCENTER | VCENTER:
				x -= w / 2;
				y -= h / 2;
				break;
			case HCENTER | BOTTOM:
				x -= w / 2;
				y -= h;
				break;
			case RIGHT | TOP:
				x -= w;
				break;
			case RIGHT | VCENTER:
				x -= w;
				y -= h / 2;
				break;
			case RIGHT | BOTTOM:
				x -= w;
				y -= h;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		
		float scaleX = w / (float) width;
		float scaleY = h / (float) height;
		m_matrix.postScale(scaleX, scaleY);
		m_matrix.postTranslate(x, y);
		
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
		}
	}
	
	public void drawBitmap(Bitmap bitmap, float x, float y, float w, float h, int anchor, boolean grey)
	{
		m_paint.reset();
		m_matrix.reset();
		ColorMatrixColorFilter cmcf;
		if (grey) {
			m_colorMatrix.reset();
			m_colorMatrix.setSaturation(0);
			cmcf = new ColorMatrixColorFilter(m_colorMatrix);
			m_paint.setColorFilter(cmcf);
			
		}
		
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		
		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= h / 2;
				break;
			case LEFT | BOTTOM:
				y -= h;
				break;
			case HCENTER | TOP:
				x -= w / 2;
				break;
			case HCENTER | VCENTER:
				x -= w / 2;
				y -= h / 2;
				break;
			case HCENTER | BOTTOM:
				x -= w / 2;
				y -= h;
				break;
			case RIGHT | TOP:
				x -= w;
				break;
			case RIGHT | VCENTER:
				x -= w;
				y -= h / 2;
				break;
			case RIGHT | BOTTOM:
				x -= w;
				y -= h;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		
		float scaleX = w / (float) width;
		float scaleY = h / (float) height;
		m_matrix.postScale(scaleX, scaleY);
		m_matrix.postTranslate(x, y);
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
		}
	}

	public void drawRegion(Bitmap bitmap, float srcx, float srcy, float width, float height, int trans, float destx, float desty,
			int anchor)
	{
		if (srcx < 0 || srcy < 0)
			return;
		if (srcx + width > bitmap.getWidth()) {
			width = bitmap.getWidth() - srcx;
		}
		if (srcy + height > bitmap.getHeight()) {
			height = bitmap.getHeight() - srcy;
		}
		m_matrix.reset();
		m_paint.reset();
		float x = destx;
		float y = desty;
		float cx = destx;
		float cy = desty;
		float cw = width;
		float ch = height;
		switch (trans) {
			case TRANS_NONE:
				x -= srcx;
				y -= srcy;
				break;
			case TRANS_MIRROR:
				m_matrix.postScale(-1, 1);
				x += srcx + width;
				y -= srcy;
				break;
			case TRANS_MIRROR_ROT180:
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(180);
				x -= srcx;
				y += srcy + height;
				break;
			case TRANS_MIRROR_ROT270:
				cw = height;
				ch = width;
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(270);
				x -= srcy;
				y -= srcx;
				break;
			case TRANS_MIRROR_ROT90:
				cw = height;
				ch = width;
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(90);
				x += srcy + height;
				y += srcx + width;
				break;
			case TRANS_ROT180:
				m_matrix.postRotate(180);
				x += srcx + width;
				y += srcy + height;
				break;
			case TRANS_ROT270:
				cw = height;
				ch = width;
				m_matrix.postRotate(270);
				x -= srcy;
				y += srcx + width;
				break;
			case TRANS_ROT90:
				cw = height;
				ch = width;
				m_matrix.postRotate(90);
				x += srcy + height;
				y -= srcx;
				break;
		}

		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= ch / 2;
				cy -= ch / 2;
				break;
			case LEFT | BOTTOM:
				y -= ch;
				cy -= ch;
				break;
			case HCENTER | TOP:
				x -= cw / 2;
				cx -= cw / 2;
				break;
			case HCENTER | VCENTER:
				x -= cw / 2;
				y -= ch / 2;
				cx -= cw / 2;
				cy -= ch / 2;
				break;
			case HCENTER | BOTTOM:
				x -= cw / 2;
				y -= ch;
				cx -= cw / 2;
				cy -= ch;
				break;
			case RIGHT | TOP:
				x -= cw;
				cx -= cw;
				break;
			case RIGHT | VCENTER:
				x -= cw;
				y -= ch / 2;
				cx -= cw;
				cy -= ch / 2;
				break;
			case RIGHT | BOTTOM:
				x -= cw;
				y -= ch;
				cx -= cw;
				cy -= ch;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		setClip((int)cx, (int)cy, (int)cw, (int)ch);
		m_matrix.postTranslate(x, y);
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
		}
	}
	
	public void drawRegion(Bitmap bitmap, float srcx, float srcy, float width, float height, int trans, float destx, float desty, float destw, float desth, 
			int anchor)
	{
		if (srcx < 0 || srcy < 0)
			return;
		if (srcx + width > bitmap.getWidth()) {
			width = bitmap.getWidth() - srcx;
		}
		if (srcy + height > bitmap.getHeight()) {
			height = bitmap.getHeight() - srcy;
		}
		m_matrix.reset();
		m_paint.reset();
		float x = 0;
		float y = 0;
		float cx = destx;
		float cy = desty;
		float cw = destw;
		float ch = desth;
		
		switch (trans) {
			case TRANS_NONE:
				x -= srcx;
				y -= srcy;
				break;
			case TRANS_MIRROR:
				m_matrix.postScale(-1, 1);
				x += srcx + width;
				y -= srcy;
				break;
			case TRANS_MIRROR_ROT180:
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(180);
				x -= srcx;
				y += srcy + height;
				break;
			case TRANS_MIRROR_ROT270:
				cw = desth;
				ch = destw;
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(270);
				x -= srcy;
				y -= srcx;
				break;
			case TRANS_MIRROR_ROT90:
				cw = desth;
				ch = destw;
				m_matrix.postScale(-1, 1);
				m_matrix.postRotate(90);
				x += srcy + height;
				y += srcx + width;
				break;
			case TRANS_ROT180:
				m_matrix.postRotate(180);
				x += srcx + width;
				y += srcy + height;
				break;
			case TRANS_ROT270:
				cw = desth;
				ch = destw;
				m_matrix.postRotate(270);
				x -= srcy;
				y += srcx + width;
				break;
			case TRANS_ROT90:
				cw = desth;
				ch = destw;
				m_matrix.postRotate(90);
				x += srcy + height;
				y -= srcx;
				break;
		}
		
		float scaleX = cw / (float) width;
		float scaleY = ch / (float) height;
		m_matrix.postScale(scaleX, scaleY);
		m_matrix.postTranslate(destx + x * scaleX, desty + y * scaleY);

		switch (anchor) {
			case 0:
			case LEFT | TOP:
				break;
			case LEFT | VCENTER:
				y -= ch / 2;
				cy -= ch / 2;
				break;
			case LEFT | BOTTOM:
				y -= ch;
				cy -= ch;
				break;
			case HCENTER | TOP:
				x -= cw / 2;
				cx -= cw / 2;
				break;
			case HCENTER | VCENTER:
				x -= cw / 2;
				y -= ch / 2;
				cx -= cw / 2;
				cy -= ch / 2;
				break;
			case HCENTER | BOTTOM:
				x -= cw / 2;
				y -= ch;
				cx -= cw / 2;
				cy -= ch;
				break;
			case RIGHT | TOP:
				x -= cw;
				cx -= cw;
				break;
			case RIGHT | VCENTER:
				x -= cw;
				y -= ch / 2;
				cx -= cw;
				cy -= ch / 2;
				break;
			case RIGHT | BOTTOM:
				x -= cw;
				y -= ch;
				cx -= cw;
				cy -= ch;
				break;
			default:
				throw new IllegalArgumentException("drawBitmap() parameter error!");
		}
		setClip((int)cx, (int)cy, (int)cw, (int)ch);
		
		if (DEBUG_GRAPHICS) {
			long start = System.nanoTime();
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
			long end = System.nanoTime();
			DrawBitmapTimes += end - start;
			DrawBitmapSquareAmount += bitmap.getWidth() * bitmap.getHeight();
			DrawBitmapCount++;
		}
		else {
			m_canvas.drawBitmap(bitmap, m_matrix, m_paint);
		}
	}

	public void setColor(int a, int r, int g, int b)
	{
		m_paint.setARGB(a, r, g, b);
	}

	/**
	 * 设置颜色（强制变成不透明）
	 * @param color
	 */
	public void setColor(int color)
	{
		m_paint.setColor(color);
	}
	
	/**
	 * 设置半透明颜色
	 * @param color
	 */
	public void setTranslucentColor(int color)
	{
		m_paint.setColor(color);
	}

	public void setAlpha(int a)
	{
		m_paint.setAlpha(a);
	}

	public void setAntiAlias(boolean aa)
	{
		m_paint.setAntiAlias(aa);
	}

	public void fillRect(int x, int y, int w, int h)
	{
		m_paint.setStyle(Style.FILL);
		m_rect.left = x;
		m_rect.top = y;
		m_rect.right = x + w;
		m_rect.bottom = y + h;
		m_canvas.drawRect(m_rect, m_paint);
	}
	
	public void fillRect2(int x, int y, int w, int h, int[] borderColors)
	{
		Paint paint = new Paint();
		paint.setColor(0x88000000);
		paint.setStyle(Style.FILL);
		m_rect.left = x;
		m_rect.top = y;
		m_rect.right = x + w;
		m_rect.bottom = y + h;
		m_canvas.drawRect(m_rect, paint);
		
		paint.setStyle(Style.STROKE);
		m_rect.right -= 1;
		m_rect.bottom -= 1;
		for(int color : borderColors) {
			paint.setColor(color);
			m_rect.left -= 1;
			m_rect.top -= 1;
			m_rect.right += 1;
			m_rect.bottom += 1;
			m_canvas.drawRect(m_rect, paint);
		}
	}

	public void fillRect(float x, float y, float w, float h)
	{
		m_paint.setStyle(Style.FILL);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawRect(m_rect, m_paint);
	}

	public void fillRect(Rect rect)
	{
		m_paint.setStyle(Style.FILL);
		m_canvas.drawRect(rect, m_paint);
	}
	
	public void fillRoundRect(int x, int y, int w, int h, int rx, int ry)
	{
		m_paint.setStyle(Style.FILL);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawRoundRect(m_rectF, rx, ry, m_paint);
	}
	
	public void fillRoundRect(float x, float y, float w, float h, float rx, float ry)
	{
		m_paint.setStyle(Style.FILL);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawRoundRect(m_rectF, rx, ry, m_paint);
	}
	
	public void fillRoundRect(RectF rect, float rx, float ry)
	{
		m_paint.setStyle(Style.FILL);
		m_canvas.drawRoundRect(rect, rx, ry, m_paint);
	}
	
	public void fillRoundRect(Rect rect, int rx, int ry)
	{
		m_paint.setStyle(Style.FILL);
		m_rectF.left = rect.left;
		m_rectF.top = rect.top;
		m_rectF.right = rect.right;
		m_rectF.bottom = rect.bottom;
		m_canvas.drawRoundRect(m_rectF, rx, ry, m_paint);
	}

	public void fillArc(RectF oval, float startAngle, float sweepAngle)
	{
		m_paint.setStyle(Style.FILL);
		m_canvas.drawArc(oval, startAngle, sweepAngle, true, m_paint);
	}

	public void fillArc(float x, float y, float w, float h, float startAngle, float sweepAngle)
	{
		m_paint.setStyle(Style.FILL);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawArc(m_rectF, startAngle, sweepAngle, true, m_paint);
	}

	public void fillCircle(float cx, float cy, float radius)
	{
		m_paint.setStyle(Style.FILL);
		m_canvas.drawCircle(cx, cy, radius, m_paint);
	}

	public void drawRect(int x, int y, int w, int h)
	{
		m_paint.setStyle(Style.STROKE);
		m_rect.left = x;
		m_rect.top = y;
		m_rect.right = x + w;
		m_rect.bottom = y + h;
		m_canvas.drawRect(m_rect, m_paint);
	}

	public void drawLine(int x, int y, int w, int h)
	{
		m_paint.setStyle(Style.STROKE);
		m_rect.left = x;
		m_rect.top = y;
		m_rect.right = x + w;
		m_rect.bottom = y + h;
		m_canvas.drawLine(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom, m_paint);
	}
	
	public void drawLines(float x, float y, float x1, float y1,int size,int color)
	{
		m_paint.setColor(color);
		m_paint.setAntiAlias(true); 
		m_paint.setStrokeWidth(size); 
		m_canvas.drawLine(x, y, x1, y1, m_paint);
	}

	public void drawRect(float x, float y, float w, float h)
	{
		m_paint.setStyle(Style.STROKE);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawRect(m_rect, m_paint);
	}

	public void drawRect(Rect rect)
	{
		m_paint.setStyle(Style.STROKE);
		m_canvas.drawRect(rect, m_paint);
	}

	public void drawArc(RectF oval, float startAngle, float sweepAngle)
	{
		m_paint.setStyle(Style.STROKE);
		m_canvas.drawArc(oval, startAngle, sweepAngle, true, m_paint);
	}

	public void drawArc(float x, float y, float w, float h, float startAngle, float sweepAngle)
	{
		m_paint.setStyle(Style.STROKE);
		m_rectF.left = x;
		m_rectF.top = y;
		m_rectF.right = x + w;
		m_rectF.bottom = y + h;
		m_canvas.drawArc(m_rectF, startAngle, sweepAngle, true, m_paint);
	}

	public void drawCircle(float cx, float cy, float radius)
	{
		m_paint.setStyle(Style.STROKE);
		m_canvas.drawCircle(cx, cy, radius, m_paint);
	}

	/**
	 * 获得翻转状态的标记值
	 * 
	 * @param flipX
	 * 是否水平翻转
	 * @param flipY
	 * 是否垂直翻转
	 * @return
	 */
	public static int trans(boolean flipX, boolean flipY)
	{
		if (flipX) {
			if (flipY) {
				return ITrans.TRANS_ROT180;
			}
			else {
				return ITrans.TRANS_MIRROR;
			}
		}
		else {
			if (flipY) {
				return ITrans.TRANS_MIRROR_ROT180;
			}
			else {
				return ITrans.TRANS_NONE;
			}
		}
	}

	/**
	 * 获得翻转及旋转状态的标记值
	 * 
	 * @param flag
	 * int 工具导出的标记
	 * @return int
	 */
	public static int trans(int flag)
	{
		switch (flag) {
			case 1:
				return ITrans.TRANS_MIRROR;
			case 2:
				return ITrans.TRANS_MIRROR_ROT180;
			case 3:
				return ITrans.TRANS_ROT180;
			case 4:
				return ITrans.TRANS_ROT90;
			case 5: // Mirror后旋转方向跟Sprite的相反 所以工具中的MIRROR_ROT90 ==
				// DWITrans中的TRANS_MIRROR_ROT270
				return ITrans.TRANS_MIRROR_ROT270;
			case 6: // Mirror后旋转方向跟Sprite的相反 所以工具中的MIRROR_ROT270 ==
				// DWITrans中的TRANS_MIRROR_ROT90
				return ITrans.TRANS_MIRROR_ROT90;
			case 7:
				return ITrans.TRANS_ROT270;
			default:
				return ITrans.TRANS_NONE;
		}
	}
	
	public void clear(int color)
	{
		setClip(0, 0, m_width, m_height);
		setColor(color);
		fillRect(0, 0, m_width, m_height);
	}
}
